package com.system.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.dao.*;
import com.system.druid.DataSource;
import com.system.druid.DataSourceType;
import com.system.entity.dto.SearchDTO;
import com.system.entity.dto.UserRoleEditDTO;
import com.system.entity.manage.*;
import com.system.entity.vo.RoleDataVO;
import com.system.entity.vo.RoleVO;
import com.system.utils.CastUtil;
import com.system.utils.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 系统相关业务层
 *
 * @Author 佛冷
 * @Date 2020/5/25 15:32
 */
@Service
public class SystemService {

    private static final Logger logger = LoggerFactory.getLogger(SystemService.class);

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysPageDao sysPageDao;
    @Autowired
    private SysRoleDao tMgrRoleDao;
    @Autowired
    private BaseDao baseDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysRolePageDao sysRolePageDao;
    @Autowired
    private SysLogDao sysLogDao;

    /**
     * 根据id获取用户信息
     *
     * @Author 佛冷
     * @Date 2020/5/25 15:39
     */
    @DataSource(DataSourceType.MASTER)
    public SysUser getUser(Integer userId) {
        return sysUserDao.selectById(userId);
    }

    /**
     * 获取用户列表
     *
     * @Author 佛冷
     * @Date 2020/5/25 15:39
     */
    @DataSource(DataSourceType.MASTER)
    public IPage<SysUser> listUser(SearchDTO dto) {
        Page<SysUser> userPage = new Page<>(dto.getPageNum(), dto.getPageSize());
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(dto.getKeyword()), "username", dto.getKeyword());
        IPage<SysUser> userIPage = sysUserDao.selectPageList(userPage, dto);
        return userIPage;
    }

    /**
     * 编辑用户信息
     *
     * @author 佛冷
     * @date 2019/10/10
     */
    @DataSource(DataSourceType.MASTER)
    public int editUser(SysUser dto) {

        boolean flag = verifyUsername(dto.getUserId(), dto.getUsername());
        if (flag) {
            logger.info("该用户名已存在");
            return -1;
        }

        dto.setUpdateDate(new Date());
        int count = 0;
        if (dto.getUserId() == null) {
            // 新增用户信息
            dto.setCreateDate(new Date());
            dto.setPassword(MD5Util.getMD5String(CastUtil.castString(dto.getPassword())));
            count = sysUserDao.insert(dto);
        } else {
            SysUser temp = sysUserDao.selectById(dto.getUserId());
            if (!dto.getPassword().equals(temp.getPassword())) {
                dto.setPassword(MD5Util.getMD5String(CastUtil.castString(dto.getPassword())));
            }
            count = sysUserDao.updateById(dto);
        }

        // 编辑权限信息
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", dto.getUserId());
        sysUserRoleDao.delete(queryWrapper);
        if (StringUtils.isNotBlank(dto.getRoleIds())) {
            List<String> roleIdList = Arrays.asList(dto.getRoleIds().split(","));
            List<SysUserRole> addList = new ArrayList<>(roleIdList.size());
            SysUserRole sysUserRole;
            for (String roleId : roleIdList) {
                sysUserRole = new SysUserRole();
                sysUserRole.setUserId(dto.getUserId());
                sysUserRole.setRoleId(Integer.parseInt(roleId));
                addList.add(sysUserRole);
            }
            sysUserDao.insertUserRoleList(addList);
        }
        return count;
    }

    /**
     * 编辑用户权限
     *
     * @author 佛冷
     * @date 2021/4/25
     */
    @DataSource(DataSourceType.MASTER)
    public int editUserRoles(SysUser dto) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", dto.getUserId());
        sysUserRoleDao.delete(queryWrapper);

        List<String> roleIdList = Arrays.asList(dto.getRoleIds().replace("，", ",").split(","));
        List<SysUserRole> addList = new ArrayList<>(roleIdList.size());
        for (String roleId : roleIdList) {
            addList.add(new SysUserRole(dto.getUserId(), Integer.parseInt(roleId)));
        }
        return sysUserDao.insertUserRoleList(addList);
    }

    /**
     * 编辑用户状态
     *
     * @author 佛冷
     * @date 2021/4/25
     */
    @DataSource(DataSourceType.MASTER)
    public int editUserStatus(SysUser dto) {
        return sysUserDao.updateById(dto);
    }

    /**
     * 删除用户信息
     *
     * @author 佛冷
     * @date 2019/10/10
     */
    @DataSource(DataSourceType.MASTER)
    public int delUser(Integer userId) {
        int count = sysUserDao.deleteById(userId);
        if (count > 0) {
            // 删除该用户角色关联
            QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId);
            sysUserRoleDao.delete(queryWrapper);
        }
        return count;
    }

    /**
     * 获取页面配置列表
     *
     * @author 佛冷
     * @date 2019/12/19
     */
    @DataSource(DataSourceType.MASTER)
    public IPage<SysPage> listPage(SearchDTO dto) {
        Page<SysPage> pagePage = new Page<>(dto.getPageNum(), dto.getPageSize());
        IPage<SysPage> result = sysPageDao.selectPageList(pagePage, dto);
        return result;
    }

    /**
     * 获取页面配置列表
     *
     * @author 佛冷
     * @date 2019/12/19
     */
    @DataSource(DataSourceType.SLAVE)
    public List<SysPage> listPage(Integer pageId) {
        QueryWrapper<SysPage> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("page_id", pageId).eq("type", 0);
        return sysPageDao.selectList(queryWrapper);
    }


    /**
     * 编辑页面信息
     *
     * @author 佛冷
     * @date 2019/10/10
     */
    @DataSource(DataSourceType.MASTER)
    public int editPage(SysPage dto) {
        int count = 0;
        dto.setUpdateDate(new Date());
        if (dto.getPageId() == null) {
            dto.setCreateDate(new Date());
            return sysPageDao.insert(dto);
        }

        SysPage sysPage = sysPageDao.selectById(dto.getPageId());
        if (sysPage == null) {
            return count;
        }

        // 将目录类型菜单修改成菜单类型，则验证之前目录下是或有子菜单
        if (sysPage.getType() == 0 && dto.getType() == 1) {
            QueryWrapper<SysPage> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id", dto.getPageId());
            int size = sysPageDao.selectCount(queryWrapper);
            if (size > 0) {
                return -1;
            }
        }
        return sysPageDao.updateById(dto);
    }

    /**
     * 修改页面状态
     *
     * @author 佛冷
     * @date 2021/4/28
     */
    @DataSource(DataSourceType.MASTER)
    public int editPageStatus(SysPage dto) {
        return sysPageDao.updateById(dto);
    }


    /**
     * 删除页面信息
     *
     * @author 佛冷
     * @date 2019/10/10
     */
    @DataSource(DataSourceType.MASTER)
    public int delPage(Integer pageId) {
        SysPage sysPage = sysPageDao.selectById(pageId);
        if (sysPage == null) {
            return 1;
        }
        // 菜单类型目录则要验证该目录下是否有子菜单，有则不能删除
        if (sysPage.getType() == 0) {
            QueryWrapper<SysPage> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id", pageId);
            int size = sysPageDao.selectCount(queryWrapper);
            if (size > 0) {
                return -1;
            }
        }

        int count = sysPageDao.deleteById(pageId);
        if (count > 0) {
            // 删除该用户角色关联
            QueryWrapper<SysRolePage> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("page_id", pageId);
            sysRolePageDao.delete(queryWrapper);
        }
        return count;
    }

    /**
     * 获取角色列表
     *
     * @author 佛冷
     * @date 2019/12/19
     */
    @DataSource(DataSourceType.MASTER)
    public IPage<SysRole> listRole(SearchDTO dto) {
        Page<SysRole> rolePage = new Page<>(dto.getPageNum(), dto.getPageSize());
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(dto.getKeyword()), "name", dto.getKeyword());
        IPage<SysRole> result = tMgrRoleDao.selectPage(rolePage, queryWrapper);
        return result;
    }

    /**
     * 获取角色列表
     *
     * @author 佛冷
     * @date 2019/12/19
     */
    @DataSource(DataSourceType.MASTER)
    public List<SysRole> listRole() {
        return tMgrRoleDao.selectList(new QueryWrapper<>());

    }

    /**
     * 获取角色权限信息
     *
     * @Author 佛冷
     * @Date 2020/5/26 10:00
     */
    @DataSource(DataSourceType.MASTER)
    public RoleDataVO listRolePage(Integer roleId) throws CloneNotSupportedException {
        // 用户已配权限集合
        List<RoleVO> userRoleVoList = new ArrayList<>();
        // 用户未配权限集合
        List<RoleVO> roleVoList = new ArrayList<>();

        // 设置菜单权限
        List<RoleVO> userRole = sysPageDao.listRolePage(roleId);
        userRoleVoList.addAll(userRole);

        List<RoleVO> roleUserRole = getPage(sysPageDao.listNotRolePage(roleId));
        roleVoList.addAll(roleUserRole);

        RoleDataVO roleDataVo = new RoleDataVO();
        roleDataVo.setUserRoleList(userRoleVoList);
        roleDataVo.setRoleList(roleVoList);
        return roleDataVo;
    }

    /**
     * 编辑角色权限信息
     *
     * @Author 佛冷
     * @Date 2020/5/26 13:30
     */
    @DataSource(DataSourceType.MASTER)
    public int editRolePage(UserRoleEditDTO dto) {
        QueryWrapper<SysRolePage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", dto.getRoleId());
        int count = sysRolePageDao.delete(queryWrapper);
        if (StringUtils.isBlank(dto.getPageIds())) {
            return count;
        }
        List<String> pageIdList = Arrays.asList(dto.getPageIds().split(","));
        List<SysRolePage> addList = new ArrayList<>();
        SysRolePage sysRolePage;
        for (String pageId : pageIdList) {
            sysRolePage = new SysRolePage();
            sysRolePage.setPageId(Integer.parseInt(pageId));
            sysRolePage.setRoleId(dto.getRoleId());
            addList.add(sysRolePage);
        }

        //批量新增
        count = sysPageDao.insertRolePageList(addList);
        return count;
    }


    /**
     * 编辑角色
     *
     * @author 佛冷
     * @date 2019/10/10
     */
    @DataSource(DataSourceType.MASTER)
    public int editRole(SysRole dto) {
        dto.setUpdateDate(new Date());
        SysRole temp = tMgrRoleDao.selectById(dto.getRoleId());
        if (temp == null) {
            dto.setCreateDate(new Date());
            return tMgrRoleDao.insert(dto);
        }
        return tMgrRoleDao.updateById(dto);
    }

    /**
     * 删除角色
     *
     * @author 佛冷
     * @date 2019/10/10
     */
    @DataSource(DataSourceType.MASTER)
    public int delRole(Integer roleId) {
        int count = tMgrRoleDao.deleteById(roleId);
        if (count > 0) {
            // 删除该角色页面关联
            QueryWrapper<SysRolePage> roleWrapper = new QueryWrapper<>();
            roleWrapper.eq("role_id", roleId);
            sysRolePageDao.delete(roleWrapper);

            // 删除该角色用户关联
            QueryWrapper<SysUserRole> userWrapper = new QueryWrapper<>();
            userWrapper.eq("role_id", roleId);
            sysUserRoleDao.delete(userWrapper);
        }
        return count;
    }


    /**
     * 获取菜单信息
     *
     * @Author 佛冷
     * @Date 2020/5/25 17:27
     */
    @DataSource(DataSourceType.MASTER)
    private List<RoleVO> getPage(List<RoleVO> pageList) {
        // 构建菜单返回数据
        List<RoleVO> returnList = new ArrayList();
        // 先找到所有的一级菜单
        for (RoleVO roleVo : pageList) {
            // 一级菜单parentId == 0
            if ("0".equals(roleVo.getPid())) {
                roleVo.setPid("0");
                returnList.add(roleVo);
            }
        }

        // 为一级菜单设置子菜单，getChild是递归调用的
        for (RoleVO roleVo : returnList) {
            roleVo.setChildren(getChild(roleVo.getId(), pageList));
        }
        return returnList;
    }


    /**
     * 删除没有子菜单的目录菜单
     *
     * @Author 佛冷
     * @Date 2020/5/28 16:46
     */
    private void removeRole(List<RoleVO> rootMenu) {
        Iterator<RoleVO> it = rootMenu.iterator();
        while (it.hasNext()) {
            RoleVO roleVO = it.next();
            // url 为空则为目录菜单
            if (StringUtils.isBlank(roleVO.getUrl())) {
                // 菜单中的子菜单不为空，则递归删除子菜单中的菜单
                if (!CollectionUtils.isEmpty(roleVO.getChildren())) {
                    removeRole(roleVO.getChildren());
                    // 子菜单递归后,再次判断当前roleVo的子菜单是否为空
                    if (CollectionUtils.isEmpty(roleVO.getChildren())) {
                        it.remove();
                    }
                } else {
                    it.remove();
                }
            }
        }
    }

    private List<RoleVO> getChild(String id, List<RoleVO> rootMenu) {
        // 子菜单
        List<RoleVO> childList = new ArrayList<>();
        for (RoleVO roleVo : rootMenu) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if (!"0".equals(roleVo.getPid())) {
                if (roleVo.getPid().equals(id)) {
                    childList.add(roleVo);
                }
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (RoleVO page : childList) {
            // 没有url子菜单还有子菜单
            if (StringUtils.isBlank(page.getUrl())) {
                // 递归
                page.setChildren(getChild(page.getId(), rootMenu));
            }
        } // 递归退出条件
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }


    /**
     * 验证用户名是否存在
     *
     * @author 佛冷
     * @date 2021/5/7
     */
    @DataSource(DataSourceType.MASTER)
    public boolean verifyUsername(Integer userId, String username) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username).ne(userId != null, "user_id", userId);
        List<SysUser> userList = sysUserDao.selectList(queryWrapper);
        return CollectionUtils.isEmpty(userList) ? false : true;
    }


    /**
     * 验证用户名是否存在
     *
     * @author 佛冷
     * @date 2021/5/7
     */
    @DataSource(DataSourceType.MASTER)
    public boolean saveSysLog(SysLog sysLog) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return sysLogDao.insert(sysLog) > 0 ? true : false;
    }


    /**
     * 获取操作日志
     *
     * @author 佛冷
     * @date 2019/12/19
     */
    @DataSource(DataSourceType.MASTER)
    public IPage<SysLog> pageSysRole(SearchDTO dto) {
        Page<SysLog> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        QueryWrapper<SysLog> queryWrapper = new QueryWrapper<>();
        boolean flag = StringUtils.isNotBlank(dto.getStartDate()) && StringUtils.isNotBlank(dto.getEndDate());
        queryWrapper.eq(StringUtils.isNotBlank(dto.getKeyword()), "username", dto.getKeyword());
        queryWrapper.apply(flag, "create_time >= {0} and create_time < DATE_ADD({1},INTERVAL 1 DAY) ", dto.getStartDate(), dto.getEndDate());
        queryWrapper.orderByDesc("id");
        IPage<SysLog> result = sysLogDao.selectPage(page, queryWrapper);
        return result;
    }
}
